package demo.dcs.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;

/**
 * Created by buffoon.wei on 15/10/13.
 */
public class XdcsC3p0ComboPooledReflectUtil {

    private static final Logger logger = LoggerFactory.getLogger(XdcsC3p0ComboPooledReflectUtil.class);

    /**
     * 反射拿c3p0 combo pool是否close的值
     * @param pool
     * @return
     */
    public static boolean isPoolClosed(Object pool){

        boolean isClosed = false;

        if (pool==null){
            return true;
        }

        if (pool instanceof com.mchange.v2.c3p0.ComboPooledDataSource){//0.9.5-pre10
            try {
                Field isCloseField = C3p0ComboPoolFieldsCache.getInstance().getIsClosedFiled();
                if (isCloseField==null) {
                	return true;
				}
                isClosed = (Boolean)isCloseField.get(pool);
            } catch (Throwable e) {
                logger.error("get com.mchange.v2.c3p0.ComboPooledDataSource isCloseField error", e);
            }
        }
        return isClosed;
    }

    private static class C3p0ComboPoolFieldsCache {
        private static C3p0ComboPoolFieldsCache instance;
        private final Field isClosedFiled;

        private C3p0ComboPoolFieldsCache() throws Exception {
        	Field field = null;
        	try {
                field = com.mchange.v2.c3p0.PoolBackedDataSource.class.getDeclaredField("is_closed");
            } catch (Exception e) {
                try {
                    field = com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.class.getDeclaredField("is_closed");
                } catch (Exception e2) {
					logger.error("get com.mchange.v2.c3p0.PoolBackedDataSource isCloseField error from xdcs", e2);
				}
				
			}
        	isClosedFiled = field;
        	if (isClosedFiled!=null) {
        		isClosedFiled.setAccessible(true);
			}
           
        }

        public static C3p0ComboPoolFieldsCache getInstance()throws Exception {

            if (instance == null) {
                synchronized (C3p0ComboPoolFieldsCache.class) {
                    if (instance == null) {
                        instance = new C3p0ComboPoolFieldsCache();
                    }
                }
            }
            return instance;
        }

        public Field getIsClosedFiled() {
            return isClosedFiled;
        }
    }
}
